package com.dx.financehy.modules.system.rest;

import cn.hutool.core.util.BooleanUtil;
import com.dx.financehy.annotation.Log;
import com.dx.financehy.annotation.rest.AnonymousDeleteMapping;
import com.dx.financehy.annotation.rest.AnonymousPostMapping;
import com.dx.financehy.config.RsaProperties;
import com.dx.financehy.exception.BadRequestException;
import com.dx.financehy.modules.file.domain.dto.FileBizDTO;
import com.dx.financehy.modules.file.domain.vo.FileVO;
import com.dx.financehy.modules.file.service.FileService;
import com.dx.financehy.modules.platformClassOne.domain.PlatformClassOne;
import com.dx.financehy.modules.platformClassOne.domain.dto.AddPlatformClassDTO;
import com.dx.financehy.modules.platformClassOne.domain.dto.DelPlatformClassDTO;
import com.dx.financehy.modules.platformClassOne.domain.dto.EditPlatformClassDTO;
import com.dx.financehy.modules.platformClassOne.domain.dto.GetPlatformClassDTO;
import com.dx.financehy.modules.schedule.domain.dto.AddEditScheduleDTO;
import com.dx.financehy.modules.schedule.domain.dto.GetScheduleDTO;
import com.dx.financehy.modules.schedule.domain.vo.ScheduleVO;
import com.dx.financehy.modules.schedule.service.ScheduleService;
import com.dx.financehy.modules.security.domain.dto.JwtUserDto;
import com.dx.financehy.modules.security.security.TokenProvider;
import com.dx.financehy.modules.security.service.OnlineUserService;
import com.dx.financehy.modules.security.utils.SecurityPlusUtils;
import com.dx.financehy.modules.system.domain.dto.*;
import com.dx.financehy.modules.system.domain.vo.GetBusinessListVO;
import com.dx.financehy.modules.system.domain.vo.IsProcessListVO;
import com.dx.financehy.modules.system.domain.vo.UserPassVo;
import com.dx.financehy.modules.system.service.UserService;
import com.dx.financehy.modules.touristMessages.domain.TouristMessages;
import com.dx.financehy.modules.touristMessages.service.TouristMessagesService;
import com.dx.financehy.utils.ConvertUtil;
import com.dx.financehy.utils.PasswordValidation;
import com.dx.financehy.utils.R;
import com.dx.financehy.utils.RsaUtils;
import com.dx.financehy.utils.security.SecurityUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: huang_jigao
 * @Title: UserController
 * @ProjectName: financehy
 * @Description:
 * @date: 2023-12-05 14:52
 */
@Api(tags = "系统：用户管理")
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Slf4j
public class UserController {

    private final PasswordEncoder passwordEncoder;
    private final OnlineUserService onlineUserService;
    private final TokenProvider tokenProvider;
    private final UserService userService;
    private final TouristMessagesService touristMessagesService;
    private final FileService fileService;
    private final ScheduleService scheduleService;

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation("获取用户信息")
    @PostMapping("/getUserInfo")
    private R<JwtUserDto> getUserInfo() {
        JwtUserDto currentUser = (JwtUserDto) SecurityPlusUtils.getCurrentUser();
        UserLoginDto user = currentUser.getUser();
        user.setPassword(null);

        return R.ok(currentUser);
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation("退出登录")
    @AnonymousDeleteMapping(value = "/logout")
    public R<Object> logout(HttpServletRequest request) {
        onlineUserService.logout(tokenProvider.getToken(request));
        return R.ok();
    }


    @ApiOperationSupport(author = "itHuang")
    @ApiOperation(value = "新增用户")
    @PostMapping("/addSysUser")
    public R addSysUser(@RequestBody @Validated AddUserDTO req) {
        userService.addSysUser(req);
        return R.ok();
    }

    @ApiOperationSupport(author = "itHuang")
    @Log("修改个人资料")
    @ApiOperation(value = "修改个人资料")
    @PostMapping("/editSysUser")
    public R<Object> update(@Validated @RequestBody UserDto resources) throws Exception {
        userService.updateById(resources);
        return R.ok("修改成功！");
    }

    @ApiOperationSupport(author = "itHuang")
    @Log("删除用户")
    @ApiOperation(value = "删除个人资料")
    @PostMapping("/delSysUser")
    public R delSysUser(@Validated @RequestBody BaseDTO req) throws Exception {
        userService.delSysUser(req);
        return R.ok();
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation("修改密码")
    @PostMapping(value = "/updatePass")
    public R<Object> updatePass(@RequestBody UserPassVo passVo,HttpServletRequest request) throws Exception {
        String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, passVo.getOldPass());
        String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, passVo.getNewPass());
        UserDto user = ConvertUtil.convert(userService.getByUsername(SecurityUtils.getCurrentUsername()), UserDto.class);
        if (!passwordEncoder.matches(oldPass, user.getPassword())) {
            throw new BadRequestException("修改失败，旧密码错误");
        }
        if (passwordEncoder.matches(newPass, user.getPassword())) {
            throw new BadRequestException("新密码不能与旧密码相同");
        }
        //验证密码是否合规
        String checkResult = PasswordValidation.checkPwd(newPass);
        if (!BooleanUtil.toBoolean(checkResult)) {
            throw new BadRequestException(checkResult);
        }
        userService.updatePass(user.getUsername(), passwordEncoder.encode(newPass), tokenProvider.getToken(request));
        return R.ok("修改密码成功！");
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取商家列表")
    @PostMapping("/getBusinessList")
    public R<PageInfo<GetBusinessListVO>> getBusinessList(@RequestBody @Validated GetBusinessListDTO dto) {
        PageHelper.startPage(dto.getPage(), dto.getSize());
        List<GetBusinessListVO> list = userService.getBusinessList(dto);
        return R.ok(new PageInfo<>(list));
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取游客列表")
    @PostMapping("/getTouristList")
    public R<PageInfo<GetBusinessListVO>> getTouristList(@RequestBody @Validated GetBusinessListDTO dto) {
        PageHelper.startPage(dto.getPage(), dto.getSize());
        List<GetBusinessListVO> list = userService.getTouristList(dto);
        return R.ok(new PageInfo<>(list));
    }

    /*@ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取平台资源一级列表")
    @PostMapping("/getPlatformClassList")
    public R<PageInfo<PlatformClassOne>> getPlatformClassList(@RequestBody @Validated GetPlatformClassDTO dto) {
        PageHelper.startPage(dto.getPage(), dto.getSize());
        List<PlatformClassOne> list = userService.getPlatformClassList(dto);
        return R.ok(new PageInfo<>(list));
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取平台资源二级列表")
    @PostMapping("/getPlatformClassTwoList")
    public R<PageInfo<PlatformClassTwo>> getPlatformClassTwoList(@RequestBody @Validated GetPlatformClassTwoDTO dto) {
        return R.ok(userService.getPlatformClassTwoList(dto));
    }*/

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取待审核平台资源和主营业务")
    @AnonymousPostMapping("/getIsProcessList")
    public R<List<IsProcessListVO>> getIsProcessList(@RequestBody @Validated IsProcessListDTO dto) {
        List<IsProcessListVO> list = userService.getIsProcessList(dto);
        int skipElements = (dto.getPage() - 1) * dto.getSize();
        log.info("流分页效果：{}",list.stream().sorted(Comparator.comparing(IsProcessListVO::getCreateTime)).skip(skipElements).limit(dto.getSize()).collect(Collectors.toList()));
        return R.ok(list.stream().sorted(Comparator.comparing(IsProcessListVO::getCreateTime)).skip(skipElements).limit(dto.getSize()).collect(Collectors.toList()),list.size());
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "审核平台资源和主营业务")
    @PostMapping("/processPlatOrBusiness")
    public R processPlatOrBusiness(@RequestBody @Validated ProcessPlatOrBusinessDTO dto) {
        userService.processPlatOrBusiness(dto);
        return R.ok();
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取平台资源")
    @PostMapping("/getAllPlatformClassList")
    public R<PageInfo<PlatformClassOne>> getAllPlatformClassList(@RequestBody @Validated GetPlatformClassDTO dto) {
        PageHelper.startPage(dto.getPage(), dto.getSize());
        List<PlatformClassOne> list = userService.getAllPlatformClassList(dto);
        return R.ok(new PageInfo<>(list));
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "新增平台资源")
    @PostMapping("/addPlatformClass")
    public R addPlatformClass(@RequestBody @Validated AddPlatformClassDTO dto) {
        userService.addPlatformClass(dto);
        return R.ok();
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "编辑平台资源")
    @PostMapping("/editPlatformClass")
    public R editPlatformClass(@RequestBody @Validated EditPlatformClassDTO dto) {
        userService.editPlatformClass(dto);
        return R.ok();
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "删除平台资源")
    @PostMapping("/delPlatformClass")
    public R delPlatformClass(@RequestBody @Validated DelPlatformClassDTO dto) {
        userService.delPlatformClass(dto);
        return R.ok();
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation(value = "后台查看留言")
    @PostMapping("/getAdminTouristMessages")
    public R<PageInfo<TouristMessages>> getAdminTouristMessages(@RequestBody @Validated BasePageDTO req) {
        PageHelper.startPage(req.getPage(), req.getSize());
        List<TouristMessages> list = touristMessagesService.getAdminTouristMessages();
        return R.ok(new PageInfo<>(list));
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation(value = "后台查看留言详情")
    @GetMapping("/getAdminTouristMessagesDetail")
    public R<TouristMessages> getAdminTouristMessagesDetail(@RequestParam String messagesid) {
        return R.ok(touristMessagesService.getTouristMessagesDetail(messagesid));
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation(value = "获取商家关于我们")
    @GetMapping("/getAboutUsList")
    public R<List<FileVO>> getAboutUsList(@RequestParam String userId) {
        return R.ok(fileService.selectFileByBizId(userId));
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation(value = "上传商家关于我们文件")
    @PostMapping("/addAboutUs")
    public R addAboutUs(@RequestBody @Validated FileBizDTO fileBizREQ) throws Exception {
        fileService.updateFileBizRef(fileBizREQ);
        return R.ok();
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取待办事项")
    @PostMapping("/getScheduleList")
    public R<PageInfo<ScheduleVO>> getScheduleList(@RequestBody @Validated GetScheduleDTO req) {
        PageHelper.startPage(req.getPage(), req.getSize());
        List<ScheduleVO> list = scheduleService.getList(req);
        return R.ok(new PageInfo<>(list));
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "获取待办事项详情")
    @PostMapping("/getScheduleDetail")
    public R<ScheduleVO> getScheduleDetail(@RequestBody @Validated BaseDTO req) {
        return R.ok(scheduleService.getScheduleDetail(req));
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "新增编辑待办事项")
    @PostMapping("/addSchedule")
    public R addSchedule(@RequestBody @Validated AddEditScheduleDTO dto) {
        scheduleService.addSchedule(dto);
        return R.ok();
    }

    @ApiOperationSupport(author = "黄基高")
    @ApiOperation(value = "删除待办事项")
    @PostMapping("/delSchedule")
    public R delSchedule(@RequestBody @Validated BaseDTO dto) {
        scheduleService.delSchedule(dto);
        return R.ok();
    }
}
